/*
 * SecureFile.cpp
 *
 *  Created on: Aug 29, 2011
 *      Author: Gherman Alin
 */

#include "SecureFile.h"
#include "serialization.h"
#include <fstream>

namespace DataAccess {

const char * DEFAULT_NAME = "archive";
const char * DEFAULT_EXT = ".algh";

SecureFile::SecureFile() :
		filePath(DEFAULT_NAME) {
	setContainer("", "");
}

SecureFile::SecureFile(const std::string& _fileName) :
		filePath(_fileName) {
	setContainer("", "");
}

SecureFile::~SecureFile() {
}

bool SecureFile::setContainer(const std::string& name, const std::string& pass) {
	boost::mutex::scoped_lock l(thisMutex);
	SecureContainer *sc = getContainer(name);
	if (NULL == sc) {
		containers[name] = SecureContainer(pass);
		return true;
	}
	return containers[name].setPasswordAndDecrypt(pass);
}

bool SecureFile::removeContainer(const std::string& name) {
	boost::mutex::scoped_lock l(thisMutex);
	containers.erase(name);
	return true;
}

bool SecureFile::load(const std::string& filePath) {
	boost::mutex::scoped_lock l(thisMutex);
	std::ifstream fin(filePath.c_str());
	InArchive ia(fin);
	ia & *this;
	if (!containerExists("")) {
		setContainer("", "");
	}
	return true;
}

bool SecureFile::save(const std::string& filePath) {
	boost::mutex::scoped_lock l(thisMutex);
	std::ofstream fout(filePath.c_str());
	OutArchive oa(fout);
	oa & *this;
	return true;
}

bool SecureFile::containerExists(const std::string& name) {
	return containers.find(name) != containers.end();
}

SecureContainer* SecureFile::getContainer(const std::string& name) {
	if (containerExists(name)) {
		return &containers[name];
	}
	return NULL;
}

SecureContainer* SecureFile::getOrCreateContainer(const std::string& name) {
	if (!containerExists(name)) {
		containers[name] = SecureContainer();
	}
	return &containers[name];
}

std::vector<std::string> SecureFile::getContainersNames() {
	std::vector<std::string> names;
	std::map<std::string, SecureContainer>::iterator it;
	for (it = containers.begin(); it != containers.end(); it++) {
		names.push_back(it->first);
	}
	return names;
}

std::vector<std::string> SecureFile::getKeys(const std::string& container) {
	SecureContainer *sc = getContainer(container);
	if (NULL == sc) {
		return std::vector<std::string>();
	}
	return sc->getKeys();
}

bool SecureFile::set(std::string& key, const std::string& container, const std::string& value) {
	return getOrCreateContainer(container)->set(key, value);
}

bool SecureFile::set(std::string& key, const std::string& container,
		const std::vector<char>& data) {
	return getOrCreateContainer(container)->set(key, data);
}

bool SecureFile::set(std::string& key, const std::string& container, std::istream& data) {
	return getOrCreateContainer(container)->set(key, data);
}

bool SecureFile::getStr(std::string& key, const std::string& container, std::string& out) {
	SecureContainer *sc = getContainer(container);
	if (NULL == sc) {
		return false;
	}
	return sc->getStr(key, out);
}

bool SecureFile::getData(std::string& key, const std::string& container, std::vector<char>& out) {
	SecureContainer *sc = getContainer(container);
	if (NULL == sc) {
		return false;
	}
	return sc->getData(key, out);
}

bool SecureFile::getInOutstream(const std::string& key, const std::string& container,
		std::ostream& out) {
	SecureContainer *sc = getContainer(container);
	if (NULL == sc) {
		return false;
	}
	return sc->getInOutstream(key, out);
}

bool SecureFile::remove(const std::string& key, const std::string& container) {
	SecureContainer *sc = getContainer(container);
	if (NULL == sc) {
		return false;
	}
	return sc->remove(key);
}

}
